In parallel computer processing, a single program can simultaneously run different threads (that is, independent flows of control) managed by the program. An important feature of parallel processing is dynamic loading and unloading of executable modules which are portions of an executing program. This dynamic loading and unloading is performed by support code generally called the “runtime library.” The runtime library is designed to minimize the interruption of the execution of the previously loaded software while adding a new module or removing an existing module.
A typical parallel processing system is shown schematically in FIG. 1. Processors 11-1, 11-2, 11-3, . . . 11-n are each connected to a main memory 100, which holds the runtime library 101 and the driver application 102. The runtime library is physically separate from the driver application, but is linked thereto. Modules of executable code 103-1, 103-2, 103-3, . . . 103-n, provide services used by the driver application and are loaded in the main memory when needed. A module load can consist of a single module (as shown in FIG. 1) or a module tree.
A schematic representation of a single-threaded computing environment is shown in FIG. 2. A thread in combination with a specific set of data, for execution of a particular computation, is referred to as a “context.” As shown schematically in FIG. 2, the driver application 102 issues commands to create a context 200 having module trees 201–203, resulting in the modules 103-1–103-9 being loaded in the context. It is noteworthy that a given module (e.g. 103–6) may be shared between module trees. The format of the modules is monitored and updated by the runtime library 101. Execution in this environment proceeds sequentially through module trees 201, 202 and 203.
Modules in a context are loaded into main memory and “stitched” together for efficient execution. It is desirable, of course, that stitching of new modules to previously loaded modules be performed dynamically (that is, with minimum interruption of execution).
A “system context” is a context which the runtime library uses to perform certain functions, such as module loading, garbage collection (preparing old data for deletion) and dynamic stitching. The runtime library, which can run on any context simultaneously, creates and manages the system contexts and system threads.
A parallel execution environment consists of two or more contexts with threads running independently, accessing thread-specific data or accessing locally or globally shared data. A schematic representation of a parallel computing environment is shown in FIG. 3. The environment of FIG. 3 has two contexts 301, 302 with module trees 311–313 and 321–323 respectively. Certain modules (e.g. 103–11, 103–12) may be shared between the contexts. A parallel environment is thus characterized by a plurality of contexts (threads and module trees; see FIG. 3) running on a plurality of processors (see FIG. 1). However, there need not be a one-to-one correspondence between the contexts and processors.
The modules and module trees loaded in one context are generally not visible to other contexts. A problem therefore arises when it is desired to modify the software (specifically, add or remove modules) while multiple, parallel threads are executing. For example, if a loaded module is removed while a thread is executing code contained in that module, the execution will fail (or at best yield unreliable results). Similarly, if a group of modules is to be added to a running system, this should be performed in a controlled manner in order to prevent executing threads from accessing an incomplete configuration of the added modules.
One possible way to avoid this problem is to suspend the execution of all the threads whenever a module is to be added or deleted. This approach adds to the complexity of the driver application by requiring startup, pause and shutdown routines. Furthermore, system performance is degraded as the number of threads increases.
There is a need for a software design which provides for dynamic loading and unloading of modules in a parallel computing environment, wherein sections of the software may be modified in a multithreaded system while actively running.